package mapelements.foreground;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.lang.reflect.InvocationTargetException;

import mapelements.Renderer;




//TODO documentazione

/**rappresenta un Foreground che possiede una particolare posizione nella mappa ed una
 * particolare forma. I MapObject sono elementi della mappa in grado di interagire
 * esplicitamente con l'utente.
 * 
 * <p>La <tt>shape</tt> del MapObject è importantissima per verificare le condizioni
 * cui il MapObject è sottoposto (per esempio protagonista sull'orlo di un burrone... deve cadere oppure no?).
 * In questo caso <strong>fortemente è consigliato</strong> che la shape del MapObject indichi la forma
 * che il MapObject assume rispetto alla <tt>mapResolution</tt> della mappa che lo incorpora.
 * Per esempio, se vogliamo che Fly sia rettangolare (base 1 mapResolution e altezza 2) basta che, come shape
 * useremo
 * <p>
 *  <code>public class Fly extends MapObject_FlyRenderer{
 *  	int hp;
 *		int psi;
 *    public Fly(int hp,int psi){
 *    	super(new Rectangle(0,0,1,1));
 *    	this.hp=hp;
 *    	this.psi=psi;
 *    }
 *  </code>
 * 
 * @author koldar
 * @version 1.3
 *
 * @param <RENDERER> il tipo di renderer usato per disegnare tale MapObject
 */
public class MapObject<RENDERER extends Renderer> extends Foreground<RENDERER>{

	private static final long serialVersionUID = 4795753779954104936L;
	
	/**indica la coordinata x, in unità di mapresolution, in cui il Map Object si trova all'interno della mappa.
	 * Cosa rappresenti tale coordinata poi non e' banale: in molti casi potrebbe essere
	 * l'angolo sinistro in alto del MapObject ma in alcuni casi essa potrebbe
	 * essere il baricentro dell'oggetto: e' lasciato al programmatore determinare
	 * chiaramente cosa sia poiche' in questo modo e' possibile implementare altri
	 * parametri come per esempio la grandezza del MapObject (in caso di baricentro)*/
	private int x;
	/**indica la coordinata y, in unità di mapresolution, in cui il MapObject si trova all'interno della mappa
	 * Cosa rappresenti tale coordinata poi non e' banale: in molti casi potrebbe essere
	 * l'angolo sinistro in alto del MapObject ma in alcuni casi essa potrebbe
	 * essere il baricentro dell'oggetto: e' lasciato al programmatore determinare
	 * chiaramente cosa sia poiche' in questo modo e' possibile implementare altri
	 * parametri come per esempio la grandezza del MapObject (in caso di baricentro)*/
	private int y;
	
	public MapObject(RENDERER _renderer,Shape _shape,AbstractForegroundDispatcherFactory dispatcher) {
		super(_renderer,_shape,dispatcher);
		this.x=0;
		this.y=0;
	}
	public MapObject(RENDERER _renderer,Shape _shape) {
		super(_renderer,_shape);
		this.x=0;
		this.y=0;
	}
	
	public MapObject(RENDERER _renderer){
		this(_renderer,null);
	}
	
	/**sicuramente il costruttore migliore. Trascura il renderer, impostabile più tardi poiché non indispensabile,
	 * e setta il concetto importante del MapObject, la shape.
	 * 
	 * @param _shape
	 */
	public MapObject(Shape _shape){
		this(null,_shape);
	}
	
	public MapObject(Shape _shape,AbstractForegroundDispatcherFactory factory){
		this(null,_shape,factory);
	}

	/**
	 * @return the x
	 */
	public int getX() {
		return x;
	}

	/**
	 * @param x the x to set
	 */
	public void setX(int x) {
		this.x = x;
	}

	/**
	 * @return the y
	 */
	public int getY() {
		return y;
	}

	/**
	 * @param y the y to set
	 */
	public void setY(int y) {
		this.y = y;
	}
	
	/**imposta le nuove coordinate (x;y)
	 * 
	 * @param x
	 * @param y
	 */
	public void setXY(int x,int y){
		this.x=x;
		this.y=y;
	}
	
	/**
	 * 
	 * @return ritorna le coordinate (x;y)
	 */
	public Point getXY(){
		return new Point(x,y);
	}
	
	public MapObject<RENDERER> clone() throws CloneNotSupportedException{
		MapObject<RENDERER> result=(MapObject<RENDERER>) super.clone();
		result.x=this.x;
		result.y=this.y;
		return result;
	}
	@Override
	public Shape getAbsoluteShape(){
		Rectangle copy=this.shape.getBounds();
		copy.translate(this.x,this.y);
		return copy;
	}

}
